/********************************************************************
 * Project:    MEDKit on Cortex M3
 * File:       Bluetooth.c
 *
 * Author:     Christian Baum
 ********************************************************************
 * Functionen fuer die Bluetooth-Schnittstelle des Pedelec inklusive
 * Interrupt-Handler und Senderoutine - Init nicht inbegriffen
 ********************************************************************/

#include "Bluetooth_Events.h"

extern uint8_t BT_continuous; // 1 = loop - 0 = no loop

void USART3_IRQHandler(void)
{
	if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
	{
        BT_receive();
	}
    
    if(USART_GetITStatus(USART3, USART_IT_TXE) != RESET)
    {
        BT_send();
    }
}

void BT_receive()
{
    // Receive new byte from buffer
    BT_Rx_Byte = USART_ReceiveData(USART3);
    
    // Detect beginning of new message
    if (BT_Rx_Byte == 0x10 && BT_Rx_Count > BT_Rx_Length) {
        BT_Rx_Count = 0;
    } else {
        /* Detect second byte of message:
         0 b L L L I I I I I
         L = bit of length information
         I = bit of ID information */
        if (BT_Rx_Count == 0) {
            BT_Rx_Id = BT_Rx_Byte & 0x1F;
            BT_Rx_Length = BT_Rx_Byte & 0xE0;
        }
        
        // response to received message
        switch (BT_Rx_Id) {
            case 0x00:
                BT_send_status();
                break;
            case 0x01:
                BT_send_speed();
                break;
            case 0x02:
                BT_send_current();
                break;
            case 0x03:
                BT_send_voltage();
                break;
            case 0x04:
                BT_send_temperature();
                break;
            case 0x10:
                if (BT_Rx_Count == 1)
                {
                    if (BT_Rx_Byte == 0x00) {
                        BT_continuous = 0x00;
                    }
                    if (BT_Rx_Byte == 0x01) {
                        BT_continuous = 0x01;
                    }
                }
                break;
            default:
                break;
        }
        
        BT_Rx_Count++;
    }
}

void BT_send()
{
    // Send bytes until pointer point to the same address
    if (pBT_Tx_Send != pBT_Tx_Fill)
    {
        USART_SendData(USART3, *pBT_Tx_Send);
        pBT_Tx_Send++;
        if (pBT_Tx_Send == BT_Tx_Buffer+BT_Tx_BufferSize)
        {
            pBT_Tx_Send = BT_Tx_Buffer;
        }
    }
    
    // If both pointers point to the same address diable interrupt
    if (pBT_Tx_Send == pBT_Tx_Fill)
    {
        USART_ITConfig(USART3, USART_IT_TXE, DISABLE);
    }
}

void BT_Write_Message(char id, char length, char * data)
{
    /* Write message to send buffer. Structure:
     Startbyte (0x10)
     Byte containing length and id
     Data bytes
     Endbyte (0x0D) */
     
	int i = 0;
	
    BT_Write_Buffer(0x10);
    BT_Write_Buffer((id & 0x1F) | ((length << 5) & 0xE0));
	
	for(i=0; i<length; i++)
	{
		BT_Write_Buffer(*(data+i));
	}
    
	BT_Write_Buffer(0x0D);

    /* Enable the USART3 Transmit interrupt */
	if(USART_GetITStatus(USART3, USART_IT_TXE) != ENABLE)
	{	
		USART_ITConfig(USART3, USART_IT_TXE, ENABLE);
	}
}

void BT_Write_Buffer (char new_item) 
{
    // Write one byte to the send buffer */
    *pBT_Tx_Fill = new_item;
    pBT_Tx_Fill++;
    
    // If end of buffer is reached, then start back at the front
    if (pBT_Tx_Fill == BT_Tx_Buffer+BT_Tx_BufferSize) 
    {
        pBT_Tx_Fill = BT_Tx_Buffer;
    }
}


/* Functions to different types of information to a recipient */ 

void BT_send_continuous()
{
    // Function is executed in Timer 3 every 100ms
	if (BT_continuous == 1)
	{
		BT_send_status();
		BT_send_speed();
    	BT_send_current();
    	BT_send_voltage();
		BT_send_temperature();
	}
}

void BT_send_speed()
{
    /* Drehzahl in 1/sec */
    uint8_t temp = (uint8_t)(RPM_OUT_Rotor_Speed/128);
    BT_Write_Message(1, 1, &temp);							
}

void BT_send_current()
{
    /* Strom mit Faktor 10 damit sich der Zeiger auch bewegt beim kleinen Motor */
    uint8_t temp = (int8_t)(SM_M_I_Bus_Filtered*10);
    BT_Write_Message(2, 1, &temp);							
}

void BT_send_voltage()
{
    /* Batteriesymbole zeigen Busspannung */
    uint8_t temp = (int8_t)(SM_M_U_Bus_Filtered*3);
    BT_Write_Message(3, 1, &temp);							
}

void BT_send_temperature()
{
    /* Temperature */
    uint8_t temp = (uint8_t)(SM_OUT_TEMP_FET_Degree);
    BT_Write_Message(4, 1, &temp);							
}

void BT_send_status()
{
	uint8_t temp = BT_continuous;

	if (BT_continuous == 1)
	{
		temp = temp | (BT_Tx_Id << 1); // Ausgabe 0 x I I I I I I I C
		BT_Tx_Id++;
		if (BT_Tx_Id == 100) 
		{
			BT_Tx_Id = 0;
		} 
	}
   	BT_Write_Message(0, 1, &temp);
}